package com.tubeonfire.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheManager;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import com.knowledgebooks.nlp.fasttag.FastTag;
import com.knowledgebooks.nlp.util.Tokenizer;
import com.tubeonfire.model.TagModel;

public class TagHelper {

	private static String cachePrefix = "this_is_tag_pool";
	private static boolean isRegisted = false;
	private static Cache cache = null;
	private static final Logger log = Logger.getLogger(TagHelper.class
			.getName());

	public static void initCache() {
		if (!isRegisted) {
			isRegisted = true;
			try {
				cache = CacheManager.getInstance().getCacheFactory()
						.createCache(Collections.emptyMap());
			} catch (CacheException e) {
				isRegisted = false;
			}
		}
	}

	public static List<String> youTag(String content) {
		List<String> result = new ArrayList<String>();
		try {
			TreeMap<String, String> treeTag = new TreeMap<String, String>();
			String[] words = Tokenizer.wordsToArray(content);
			String[] tags = (new FastTag()).tag(words);
			for (int i = 0; i < words.length; i++) {
				if (tags[i].equals("NN") || tags[i].equals("NNS")
						|| tags[i].equals("NNP") || tags[i].equals("NNPS")) {
					if (words[i].length() > 2) {
						treeTag.put(words[i], words[i]);
					}
					if (treeTag.size() > 30) {
						break;
					}
				}
			}
			for (String string : treeTag.keySet()) {
				result.add(string);
			}
			if (result.size() <= 6) {
				result.add("tubeonfire");
				result.add("video");
				result.add("clips");
				result.add("ilike");
				result.add("tube");
				result.add("tubeilike");
			}
		} catch (Exception e) {
			log.warning(e.getMessage());
			e.printStackTrace(System.err);
		}
		return result;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List<String> getTag(String content) {
		List<String> result = new ArrayList<String>();
		try {
			URL url = new URL("http://webmasterviet.com/tag.php");

			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.setReadTimeout(3 * 1000);
			connection.setConnectTimeout(3 * 1000);
			connection.setDoOutput(true);
			connection.setRequestMethod("POST");
			connection.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");

			OutputStreamWriter writer = new OutputStreamWriter(
					connection.getOutputStream());
			writer.write("str=" + content.replaceAll("[\\W]+", " "));
			writer.close();
			if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(connection.getInputStream()));
				StringBuilder resultContent = new StringBuilder();
				while (true) {
					String str = reader.readLine();
					if (str == null)
						break;
					resultContent.append(str);
				}
				Document doc = Jsoup.parse(resultContent.toString());
				Elements myTags = doc.select(".tag");
				initCache();
				TreeMap<String, String> tagPool = null;
				if (cache != null && cache.containsKey(cachePrefix)) {
					tagPool = (TreeMap) cache.get(cachePrefix);
				} else {
					tagPool = new TreeMap();
				}
				for (int i = 0; i < myTags.size(); i++) {
					if (myTags.get(i).text().length() < 20) {
						result.add(myTags.get(i).text().toLowerCase());
						tagPool.put(myTags.get(i).text().toLowerCase(), myTags
								.get(i).text().toLowerCase());
					}
					if (tagPool.size() > 500) {
						tagPool.pollFirstEntry();
					}
				}
				cache.put(cachePrefix, tagPool);
			}
			if (result.size() <= 6) {
				result.add("tubeonfire");
				result.add("video");
				result.add("clips");
				result.add("ilike");
				result.add("tube");
				result.add("tubeilike");
			}
			return result;

		} catch (Exception e) {
			log.warning(e.getMessage());
			e.printStackTrace(System.err);
			result.add("tubeonfire");
			result.add("video");
			result.add("clips");
			result.add("ilike");
			result.add("tube");
			result.add("tubeilike");
			return result;
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static List<String> getOtherTag(List<String> tags) {
		initCache();
		List<String> result = new ArrayList<String>();
		try {
			TreeMap<String, String> tagPool = new TreeMap<String, String>();
			List<String> keys = new ArrayList();
			TreeMap<String, String> treeTags = (TreeMap<String, String>) mapMe(tags);
			if (cache != null && cache.containsKey(cachePrefix)) {
				tagPool = (TreeMap<String, String>) cache.get(cachePrefix);
				for (String tag : tagPool.keySet()) {
					keys.add(tag);
				}
			} else {
				TagModel tagModel = new TagModel();
				keys = tagModel.getTagPool();
			}
			if (keys.size() > 0) {
				Collections.shuffle(keys);
				for (String key : keys) {
					if (key.length() > 3) {
						if (treeTags.containsKey(key)) {
							continue;
						} else {
							result.add(key);
							if (result.size() > 20) {
								break;
							}
						}
					}
				}
			}
			if (keys.size() > 100) {
				keys.subList(0, 50);
			}
			tagPool = new TreeMap<String, String>();
			tagPool.putAll(mapMe(keys));
			tagPool.putAll(treeTags);
			cache.put(cachePrefix, tagPool);
		} catch (Exception e) {
			log.warning(e.getMessage());
			e.printStackTrace(System.err);
		}
		if (result.size() <= 6) {
			result.add("tubeonfire");
			result.add("do");
			result.add("you");
			result.add("love");
			result.add("this");
			result.add("site");
		}
		return result;
	}

	public static <T> Map<String, T> mapMe(Collection<T> list) {
		TreeMap<String, T> map = new TreeMap<String, T>();
		for (T el : list) {
			map.put(el.toString(), el);
		}
		return map;
	}
}
